package org.wu.framework.lazy.orm.core.persistence.reverse.lazy.similar;

import org.wu.framework.lazy.orm.core.config.ReverseEngineering;
import org.wu.framework.lazy.orm.core.persistence.conf.LazyTableFieldEndpoint;
import org.wu.framework.lazy.orm.core.persistence.reverse.ReverseClassLazyTableEndpoint;
import org.wu.framework.lazy.orm.core.persistence.reverse.lazy.DefaultAbstractJavaReverseEngineeringMethod;
import org.wu.framework.core.NormalUsedString;

import java.io.File;
import java.util.stream.Collectors;


/**
 * 形成xml 通用接口
 */
public abstract class DefaultAbstractJavaReverseEngineeringMapperXmlMethod extends DefaultAbstractJavaReverseEngineeringMethod {

    public DefaultAbstractJavaReverseEngineeringMapperXmlMethod(ReverseClassLazyTableEndpoint reverseClassLazyTableEndpoint, ReverseEngineering reverseEngineering) {
        super(reverseClassLazyTableEndpoint, reverseEngineering);
    }

    /**
     * 创建 mapper xml中的内容
     * @return  mapper xml中的内容
     */
    public String createMapperXml(){
        ReverseClassLazyTableEndpoint tableEndpoint = this.getReverseClassLazyTableEndpoint();


        String className = tableEndpoint.getClassName();
        String packageName = tableEndpoint.getPackageName();
        String mapper = tableEndpoint.getClassName() + "Mapper";
        String tableName = tableEndpoint.getTableName();

        String class2LowName = tableEndpoint.getClass2LowName();
        setFileName(mapper);
        //   <?xml version="1.0" encoding="UTF-8"?>
        //<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
        //<mapper namespace="com.xx.dao">
        //      <resultMap id="BaseResultMap" type="com.xx.entity">
        //          <id column="id" property="id" />
        //          <result column="code" property="code" />
        //      </resultMap>
        // </mapper>
        StringBuilder classContext = new StringBuilder();
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append("<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">");
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append(String.format("<mapper namespace=\"%s\">", packageName + NormalUsedString.DOT + "infrastructure.mapper" + NormalUsedString.DOT + mapper));
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append(String.format("<resultMap id=\"BaseResultMap\" type=\"%s\">",
                packageName + NormalUsedString.DOT + "infrastructure.entity" + NormalUsedString.DOT + className + "DO"));

        for (LazyTableFieldEndpoint fieldEndpoint : tableEndpoint.getOutLazyTableFieldEndpoints()) {
            classContext.append(NormalUsedString.NEWLINE);
            String name = fieldEndpoint.getName();
            String columnName = fieldEndpoint.getColumnName();
            if ("id".equals(name)) {
                classContext.append("<id column=\"id\" property=\"id\" />");
            } else {
                classContext.append(String.format("<result column=\"%s\" property=\"%s\" />", columnName, name));
            }
        }
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append("</resultMap>");
        classContext.append(NormalUsedString.NEWLINE);


        classContext.append(NormalUsedString.NEWLINE);
        classContext.append("</mapper>");
        return classContext.toString();
    }
    /**
     * 创建 class 上下文代码
     *
     * @return Java内容编码
     */
    @Override
    public String createJavaContextCode() {
        ReverseClassLazyTableEndpoint tableEndpoint = this.getReverseClassLazyTableEndpoint();


        String className = tableEndpoint.getClassName();
        String packageName = tableEndpoint.getPackageName();
        String mapper = tableEndpoint.getClassName() + "Mapper";
        String tableName = tableEndpoint.getTableName();

        String class2LowName = tableEndpoint.getClass2LowName();
        setFileName(mapper);
        //   <?xml version="1.0" encoding="UTF-8"?>
        //<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
        //<mapper namespace="com.xx.dao">
        //      <resultMap id="BaseResultMap" type="com.xx.entity">
        //          <id column="id" property="id" />
        //          <result column="code" property="code" />
        //      </resultMap>
        // </mapper>
        StringBuilder classContext = new StringBuilder();
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append("<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">");
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append(String.format("<mapper namespace=\"%s\">", packageName + NormalUsedString.DOT + "infrastructure.mapper" + NormalUsedString.DOT + mapper));
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append(String.format("<resultMap id=\"BaseResultMap\" type=\"%s\">",
                packageName + NormalUsedString.DOT + "infrastructure.entity" + NormalUsedString.DOT + className + "DO"));

        for (LazyTableFieldEndpoint fieldEndpoint : tableEndpoint.getOutLazyTableFieldEndpoints()) {
            classContext.append(NormalUsedString.NEWLINE);
            String name = fieldEndpoint.getName();
            String columnName = fieldEndpoint.getColumnName();
            if ("id".equals(name)) {
                classContext.append("<id column=\"id\" property=\"id\" />");
            } else {
                classContext.append(String.format("<result column=\"%s\" property=\"%s\" />", columnName, name));
            }
        }
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append("</resultMap>");
        classContext.append(NormalUsedString.NEWLINE);


        classContext.append(NormalUsedString.NEWLINE);

        /**
         *     <insert id="story">
         *         insert ignore into
         *         `sys_user` (`column_name`, `create_time`, `id`, `is_deleted`, `password`, `scope`, `status`, `update_time`,`username`)
         *         VALUES
         *             (#{item.columnName},#{item.createTime},#{item.id},#{item.isDeleted},#{item.password},#{item.scope},#{item.status},#{item.updateTime},#{item.username})
         *
         *     </insert>
         */
        // story
        classContext.append("<insert id=\"story\">");
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append("insert ignore into");
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append(NormalUsedString.BACKTICK).append(tableName).append(NormalUsedString.BACKTICK);
        classContext.append(NormalUsedString.LEFT_BRACKET);
        String columnNames = tableEndpoint
                .getOutLazyTableFieldEndpoints()
                .stream()
                .map(lazyTableFieldEndpoint -> NormalUsedString.BACKTICK + lazyTableFieldEndpoint.getColumnName() + NormalUsedString.BACKTICK)
                .collect(Collectors.joining(","));
        classContext.append(columnNames);

        classContext.append(NormalUsedString.RIGHT_BRACKET);
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append(NormalUsedString.VALUES);
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append(NormalUsedString.LEFT_BRACKET);
        String valuePlaceholder = tableEndpoint
                .getOutLazyTableFieldEndpoints()
                .stream()
                .map(lazyTableFieldEndpoint -> NormalUsedString.HASH + NormalUsedString.LEFT_BRACKET + class2LowName + NormalUsedString.DOT + lazyTableFieldEndpoint.getName() + NormalUsedString.RIGHT_BRACE)
                .collect(Collectors.joining(","));

        classContext.append(valuePlaceholder);
        classContext.append(NormalUsedString.RIGHT_BRACKET);
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append("</insert>");
        classContext.append(NormalUsedString.NEWLINE);

        // batchStory
        /**
         *     <insert id="batchStory">
         *         insert ignore into
         *         `sys_user` (`column_name`, `create_time`, `id`, `is_deleted`, `password`, `scope`, `status`,
         *         `update_time`,`username`)
         *         VALUES
         *         <foreach collection="list" separator="," item="item">
         *
         *             (#{item.columnName},#{item.createTime},#{item.id},#{item.isDeleted},#{item.password},#{item.scope},#{item.status},#{item.updateTime},#{item.username})
         *
         *         </foreach>
         *     </insert>
         */
        classContext.append("<insert id=\"batchStory\">");
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append("insert ignore into");
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append(NormalUsedString.BACKTICK).append(tableName).append(NormalUsedString.BACKTICK);
        classContext.append(NormalUsedString.LEFT_BRACKET);
        classContext.append(columnNames);

        classContext.append(NormalUsedString.RIGHT_BRACKET);
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append(NormalUsedString.VALUES);
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append(String.format("<foreach collection=\"%sList\" separator=\",\" item=\"%s\">", class2LowName, class2LowName));
        classContext.append(valuePlaceholder);
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append("</foreach>");
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append("</insert>");
        classContext.append(NormalUsedString.NEWLINE);
        // update
        /**
         *     <update id="updateSysUser">
         *
         *     </update>
         *
         *        <update id="updateSysTenantAddress"
         *             parameterType="com.laihui.upms.manager.infrastructure.entity.SysTenantAddressDO">
         *         update sys_tenant_address
         *         <set>
         *             <if test="addressName != null">
         *                 address_name = #{addressName},
         *             </if>
         *
         */
        classContext.append("<update id=\"update\">");
        classContext.append(NormalUsedString.NEWLINE);

        classContext.append(" update").append(NormalUsedString.SPACE).append(tableName);
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append("<set>");
        String columnNameIfs = tableEndpoint
                .getOutLazyTableFieldEndpoints()
                .stream()
                .map(lazyTableFieldEndpoint -> {
                    String name = lazyTableFieldEndpoint.getName();
                    String columnName = lazyTableFieldEndpoint.getColumnName();
                    return String.format("""
                                     <if test="%s.%s != null and %s.%s !='' ">
                                                    %s = #{%s.%s},
                                                </if>\
                                    """,
                            class2LowName, name, class2LowName, name,
                            columnName, class2LowName, name);

                })
                .collect(Collectors.joining());
        classContext.append(columnNameIfs);

        classContext.append("</set>");
        classContext.append("</update>");
        classContext.append(NormalUsedString.NEWLINE);
        // remove

        /**
         *     <delete id="deleteById">
         *         delete
         *         from crm_audit_records
         *         <where>
         *              <if test="id!=null">
         *                  id=#{id}
         *              </if>
         *              <if test="pwd!=null">
         *                  and password=#{pwd}
         *              </if>
         *              </where>
         *     </delete>
         */

        classContext.append("<delete id=\"remove\">");

        classContext.append(NormalUsedString.NEWLINE);
        classContext.append(NormalUsedString.DELETE);
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append(NormalUsedString.FROM).append(NormalUsedString.SPACE).append(tableName);
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append("<where>");
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append(columnNameIfs);
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append("</where>");
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append("</delete>");
        classContext.append(NormalUsedString.NEWLINE);
        // findPage
        /**
         *    <select id="selectTerraceByUserId" resultType="java.lang.String">
         *         select sys_user_terrace.terrace from sys_user_terrace where user_id=#{id}
         *                                                                 and sys_user_terrace.is_delete = false
         *     </select>
         */
        classContext.append("<select id=\"findPage\">");

        classContext.append(NormalUsedString.NEWLINE);
        classContext.append("select");
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append(columnNames);
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append(NormalUsedString.FROM).append(NormalUsedString.SPACE).append(tableName);

        classContext.append("<where>");
        classContext.append(NormalUsedString.NEWLINE);

        classContext.append(columnNameIfs);

        classContext.append(NormalUsedString.NEWLINE);
        classContext.append("</where>");
        classContext.append(NormalUsedString.NEWLINE);

        classContext.append("</select>");
        classContext.append(NormalUsedString.NEWLINE);



        // findList
        classContext.append("<select id=\"findList\">");

        classContext.append(NormalUsedString.NEWLINE);
        classContext.append("select");
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append(columnNames);
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append(NormalUsedString.FROM).append(NormalUsedString.SPACE).append(tableName);
        classContext.append("<where>");
        classContext.append(NormalUsedString.NEWLINE);

        classContext.append(columnNameIfs);

        classContext.append(NormalUsedString.NEWLINE);
        classContext.append("</where>");
        classContext.append(NormalUsedString.NEWLINE);

        classContext.append("</select>");
        classContext.append(NormalUsedString.NEWLINE);




        // findOne
        classContext.append("<select id=\"findOne\">");

        classContext.append(NormalUsedString.NEWLINE);
        classContext.append("select");
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append(columnNames);
        classContext.append(NormalUsedString.NEWLINE);
        classContext.append(NormalUsedString.FROM).append(NormalUsedString.SPACE).append(tableName);

        classContext.append("<where>");
        classContext.append(NormalUsedString.NEWLINE);

        classContext.append(columnNameIfs);

        classContext.append(NormalUsedString.NEWLINE);
        classContext.append("</where>");
        classContext.append(NormalUsedString.NEWLINE);

        classContext.append("</select>");
        classContext.append(NormalUsedString.NEWLINE);

        classContext.append("</mapper>");
        return classContext.toString();
    }

    @Override
    protected String getPackage() {
        return NormalUsedString.EMPTY;
    }

    /**
     * description:  添加 class 字段片段
     *
     * <p>@LazyTableFieldId(comment = "api参数主键")</p>
     * private Long id;
     * </p>
     *
     * @author 吴佳伟
     * @date: 13.2.23 17:13
     */
    @Override
    public void initClassFieldPart() {

    }

    @Override
    public String generateClassDescribe(String comment) {
        return NormalUsedString.EMPTY;
    }

    /**
     * 获取 文件module type
     *
     * @return
     */
    @Override
    protected String getModuleType() {
        return "infrastructure" + File.separator + "xml";
    }

    /**
     * 获取文件后缀
     *
     * @return
     */
    @Override
    protected String getFileSuffix() {
        return ".xml";
    }


}
